import React, { FC, useState } from 'react'

import { Button, Form, Input, InputNumber, Modal, Spin, Table } from 'antd'

import { useSearchTankOperationQuery, SearchTankOperationDocument,_UpdateTankOperationInput, IncreaseTankValMutationVariables, DecreaseTankValMutationVariables, useIncreaseTankValMutation, useDecreaseTankValMutation, useSearchTankQuery } from '../__generate/graphql-frontend'


const columns = [
    {
        title: "Kind",
        key: 'kind',
        dataIndex: 'kind',
    },
    {
        title: "Val",
        key: 'val',
        dataIndex: 'val',
    },
    {
        title: "Transfer",
        key: 'transfer',
        dataIndex: 'transfer',
    },
]

enum ShowForm {
    None,
    Increase,
    Decrease
}

interface TankOperationListProps {
    tankId: string
}

type IncreaseParameters = Partial<IncreaseTankValMutationVariables>
type DecreaseParameters = Partial<DecreaseTankValMutationVariables>


export const TankOperationList: FC<TankOperationListProps> = ({ tankId }) => {

    const [showForm, setShowForm] = useState<ShowForm>(ShowForm.None)
    const [increaseParameters, setIncreaseParameters] = useState<IncreaseParameters>({})
    const [decreaseParameters, setDecreaseParameters] = useState<DecreaseParameters>({})

    const [increaseTankValMutation] = useIncreaseTankValMutation()
    const [decreaseTankValMutation] = useDecreaseTankValMutation()

    const { data: dataST } = useSearchTankQuery({
        variables: {
            cond: "it.$id == '" + tankId + "'"
        }
    })

    const tankData = dataST?.searchTank.elems[0]

    const { data, loading, error } = useSearchTankOperationQuery({
        variables: {
            cond: "it.tank.$id == '" + tankId + "'"
        }
    })

    const tankOperationList = data?.searchTankOperation.elems


    const changeIncreaseParameters = (params: IncreaseParameters) => {
        var input = { ...increaseParameters }
        setIncreaseParameters(Object.assign(input, params))
    }

    const changeDecreaseParameters = (params: DecreaseParameters) => {
        var input = { ...decreaseParameters }
        setDecreaseParameters(Object.assign(input, params))
    }

    const mapToView = (list: typeof tankOperationList) => {
        return (
            list?.map(elem => {
                return {
                    key: elem.id ?? "",
                    kind: elem.kind,
                    val: elem.val,
                    transfer: elem.transfer.entityId
                }
            })
        )
    }

    if (loading) return (<Spin tip="Loading..." />);
    if (error) return <p>`Error! ${error.message}`</p>;

    return (
        <>
            <Button type="primary" style={{ margin: "20px" }}
                onClick={() => {
                    setIncreaseParameters({})
                    setShowForm(ShowForm.Increase)
                }}>
                Increase operation
            </Button>

            <Button type="primary" style={{ margin: "20px" }}
                onClick={() => {
                    setDecreaseParameters({})
                    setShowForm(ShowForm.Decrease)
                }}>
                Decrease operation
            </Button>

            <Modal visible={showForm != ShowForm.None}
                onCancel={() => setShowForm(ShowForm.None)}
                onOk={() => {
                    if (showForm == ShowForm.Increase) {
                        increaseTankValMutation({
                            variables: Object.assign(increaseParameters, { tankId: tankId }) as IncreaseTankValMutationVariables
                            ,
                            update: (store, result) => {
                                // rewrite Apollo cache for search query after new element create
                                store.writeQuery({
                                    query: SearchTankOperationDocument,
                                    variables: {
                                        cond: "it.tank.$id == '" + tankId + "'"
                                    },
                                    data: {
                                        searchTankOperation: {
                                            elems: [, ...tankOperationList!, result.data?.packet?.createTankOperation]
                                        }
                                    }
                                })
                            }
                        })
                    } else if (showForm == ShowForm.Decrease) {
                        decreaseTankValMutation({
                            variables: Object.assign(decreaseParameters, { tankId: tankId }) as DecreaseTankValMutationVariables
                            ,
                            update: (store, result) => {
                                // rewrite Apollo cache for search query after new element create
                                store.writeQuery({
                                    query: SearchTankOperationDocument,
                                    variables: {
                                        cond: "it.tank.$id == '" + tankId + "'"
                                    },
                                    data: {
                                        searchTankOperation: {
                                            elems: [, ...tankOperationList!, result.data?.packet?.createTankOperation]
                                        }
                                    }
                                })
                            }
                        })
                    }
                    setShowForm(ShowForm.None)
                }}
            >
                <Form>
                    <Form.Item>{"Cuurent Tank Volume:" + tankData?.currentVal}</Form.Item>
                    <Form.Item>
                        <InputNumber placeholder="val"
                            value={showForm == ShowForm.Increase ? increaseParameters.val : decreaseParameters.val}
                            onChange={value => {
                                if (showForm == ShowForm.Increase) {
                                    changeIncreaseParameters({ val: value })
                                }
                                else {
                                    changeDecreaseParameters({ val: value })
                                }
                            }}
                        />
                    </Form.Item>
                    <Form.Item>
                        <Input placeholder="transfer"
                            value={showForm == ShowForm.Increase ? increaseParameters.transferRef?.entityId : decreaseParameters.transferRef?.entityId}
                            onChange={e => {
                                if (showForm == ShowForm.Increase) {
                                    changeIncreaseParameters({ transferRef: { entityId: e.target.value } })
                                }
                                else {
                                    changeDecreaseParameters({ transferRef: { entityId: e.target.value } })
                                }
                            }}
                        />
                    </Form.Item>
                </Form>
            </Modal>
            <Table
                columns={columns}
                dataSource={mapToView(tankOperationList)}
            />
        </>
    )
}

